import { Global, Logger, MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common';
import { CommonService } from './common.service';
import { PrismaModule } from './prisma/prisma.module';
import { APP_FILTER, APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { HttpExceptionFilter } from './filters/http-exception.filter';
import { TransformInterceptor } from './interceptors/transform.interceptor';
import { ConfigModule } from '@nestjs/config';
import { validate } from './config/validate.env';
import { envFilePath } from './config/constants';
import { RedisModule } from './redis/redis.module';
import { LoggerModule } from './logger/logger.module';
import { LogMiddleware } from './middleware/log.middleware';
import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler';
import { JwtAccessGuard } from './guards/jwt-access.guard';
import { UploadModule } from './upload/upload.module';
import { EmailModule } from './email/email.module';
import { TaskModule } from './task/task.module';
import { HttpModule } from '@nestjs/axios';

@Global()
@Module({
  imports: [
    HttpModule.register({
      timeout: 5000
    }),
    ConfigModule.forRoot({
      isGlobal: true,
      validate,
      envFilePath,
    }),
    PrismaModule,
    RedisModule,
    LoggerModule,
    ThrottlerModule.forRoot({
      throttlers: [
        {
          ttl: 1000,
          limit: 10,
        }
      ]
    }),
    UploadModule,
    EmailModule,
    TaskModule
  ],
  providers: [
    CommonService,
    Logger,
    //全局异常拦截器
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
    //全局响应结果过滤
    {
      provide: APP_INTERCEPTOR,
      useClass: TransformInterceptor,
    },
    // 限流
    {
      provide: APP_GUARD,
      useClass: ThrottlerGuard
    },
    // 全部路由使用jwt验证
    {
      provide: APP_GUARD,
      useClass: JwtAccessGuard
    }
  ],
  exports: [CommonService, Logger, PrismaModule, RedisModule, LoggerModule, EmailModule, TaskModule, HttpModule],
})

// 配置请求日志中间件
export class CommonModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LogMiddleware).forRoutes(
      { path: '*', method: RequestMethod.ALL },
    )
  }
}
